#include "defs.h"
#include "client_socket.h"
#include "uae.h"
#include <limits.h>

void getConnected(char *tipo);

void run();
void act();
void readAndUpdate();

int** Payoffs;

ClientSocket *sox;
uae* uae_alg;
int numActions;
int t = 0;
/* **************************************
*
* Agent.exe type=[row or col]
*
**************************************** */
int main(int argc, char *argv[]) {
	srand(time(NULL));
	getConnected(argv[1]);

	run();
	return 0;
}

void run() {
	while (true) {
		// decide and act
		act();

		// read and update
		readAndUpdate();

		t++;
	}
}

void act() {
	/*  ******************************************

	TODO: Determine which action to take;  This agent just plays randomly

	********************************************* */

	//printf("ready to act\n");
	int a = uae_alg->Move();//rand() % numActions;
	//printf("intended action at time %i: %i\n", t, a);

	/* ***** End Action Selection Code ***** */

	// send action
	char buf[1024];
	sprintf(buf, "%i\0", a);
	sox->SendMessage(buf, (int)strlen(buf));
}

void readAndUpdate() {
	char buf[1024];

	sox->ReadMessage(buf);

	if (!strncmp(buf, "Done", 4)) {
		printf("finished\n");
		// clean up memory
		exit(0);
	}

	//printf("update buf: %s\n", buf);

	int myaction = atoi(strtok(buf,"\n"));
	int otheraction = atoi(strtok(NULL, "\n"));
	int myPayoff = Payoffs[myaction][otheraction];

//	printf("U(%i, %i)=%i\n", myaction, otheraction, myPayoff);
	int actions[]= {myaction,otheraction};
	uae_alg->Update((int*)actions, myPayoff);

}



/* ***************************************************
*
*	You should not modify code below this line (except to modify your agent name)
*
******************************************************/
void getConnected(char *tipo) {
	char buf[1024];

	ClientSocket *root = new ClientSocket("localhost", 3000);
	root->SendMessage("c\0", (int)strlen("c\0"));
	root->ReadMessage(buf);
	delete root;

	int port = atoi(buf);
#if defined WIN32
	Sleep(100);
#else
	usleep(100*1000);
#endif
	sox = new ClientSocket("localhost", port);
	if (tipo[5] == 'r')
		sox->SendMessage("row", (int)strlen("row"));
	else
		sox->SendMessage("col", (int)strlen("col"));

	sprintf(buf, "\r\nUAE-delux\r\n\0");  //RandomC++ is the name of the agent
	sox->SendMessage(buf, (int)strlen(buf));

	// Read in world information
	sox->ReadMessage(buf);

	numActions = atoi(strtok(buf,"\n"));

	Payoffs = (int**) new int[4];
	for(int i=0; i<4; i++)
		Payoffs[i] = new int[4];

	int i, j;
	for (i = 0; i < numActions; i++) {
		for (j = 0; j < numActions; j++) {
			Payoffs[i][j] = atoi(strtok(NULL,"\n"));
		}
	}

	uae_alg = new uae(numActions, Payoffs, 0.1);
}
